package cn.itrigger.dynamic.sql.condition;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Stream;

/**
 * @author admin
 * @date 2018/9/25
 **/
public abstract class AbstractListValueCondition<T> implements VisitableCondition<T> {
    private List<T> values;

    protected AbstractListValueCondition(AbstractBuilder<T, ?> builder) {
        values = Objects.requireNonNull(builder.values);
    }

    public final <R> Stream<R> mapValues(Function<T, R> mapper) {
        return values.stream()
                .map(this::mapValue)
                .map(mapper);
    }

    @Override
    public <R> R accept(ConditionVisitor<T, R> visitor) {
        return visitor.visit(this);
    }

    protected T mapValue(T value) {
        return value;
    }

    public abstract String renderCondition(String columnName, Stream<String> placeholders);

    public abstract static class AbstractBuilder<T, B extends AbstractBuilder<T, B>> {
        private List<T> values = new ArrayList<>();

        public B withValues(List<T> values) {
            this.values.addAll(values);
            return getThis();
        }

        public abstract B getThis();
    }
}
